<?php
namespace app\job;

use think\facade\Queue;
use think\facade\Db;
use think\exception\ValidateException;
use think\queue\Job;

class JobLearning
{


    // 学习记录-课程学习明细
    public function task1(Job $job, array $data)
    {

        $isJobDone = $this->doRecordJobTask1($data);

        if ($isJobDone['code'] == 0) {

            $job->delete();

            // 1.当前任务由哪个类来负责处理
            // 当轮到该任务时，系统将生成该类的实例，并调用其fire方法
            $jobHandlerClassName = 'app\job\JobLearning@task1';

            // 2.当任务归属的队列名称，如果为新队列，会自动创建
            $jobQueueName = "LearningRecordJobQueue";


            // 3.当前任务所需业务数据，不能为resource类型，其他类型最终将转化为json形式的字符串
            $jobData = ['ts' => $isJobDone['ts'], 'download_id' => $isJobDone['download_id'], 'page' => $isJobDone['page'], 'key' => $isJobDone['key'], 'start' => $isJobDone['start'], 'end' => $isJobDone['end'], 'department' => $isJobDone['department']];

            // 4.将该任务推送到消息列表，等待对应的消费者去执行
            // 入队列，later延迟执行，单位秒，push立即执行
            Queue::push($jobHandlerClassName, $jobData, $jobQueueName);

        } else if($isJobDone['code'] == 1) {
            $job->delete();
            Db::name('document')->where('id', '=', $data['download_id'])->update(['url' => '/csv/learning/LearningRecordList-'.date('YmdHis', $data['ts']).'.csv', 'complete_time'=>time()]);
        } else {
            if ($job->attempts() > 3) {
                $job->delete();
            }

        }

    }

    /**
     * 根据消息中的数据进行实际的业务处理...
     * @param array $data
     * @return bool
     */
    protected function doRecordJobTask1(array $data)
    {
        $date = date('YmdHis', $data['ts']);
        $file_path = root_path() . "/public/csv/learning/LearningRecordList-" . $date . ".csv";


        if (!file_exists($file_path)) {
            $fp = fopen($file_path, 'a');

            //添加BOM头，以UTF8编码导出CSV文件，如果文件头未添加BOM头，打开会出现乱码。
            fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF));

            //添加导出标题
            fputcsv($fp, ['工号', '姓名', 'Division', '部门', '已学课程数', '已学完课程数', '总学习时长(s)']);
        } else {
            $fp = fopen($file_path, 'a');

            //添加BOM头，以UTF8编码导出CSV文件，如果文件头未添加BOM头，打开会出现乱码。
            fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF));
        }
        $where = [];

        if (!empty($data['department'])) {
            $where[]  = ['', 'EXP', Db::raw("CONCAT(',',e.department,',') REGEXP concat(',(',replace('".$data['department']."',',','|'),'),')")];
        }

        if (!empty($data['key'])) {
            $where[] = ['e.name|e.userid', 'like', '%' . $data['key'] . '%'];
        }

        $where[] = ['e.status', '=', 1];


        $where1 = [];
        $where2 = [];
        if (!empty($data['start']) && !empty($data['end'])) {
            $where1[] = ['add_time', 'between', [strtotime($data['start']), strtotime($data['end'])+86399]];
            $where2[] = ['add_time', 'between', [strtotime($data['start']), strtotime($data['end'])+86399]];
        }


        if (!empty($data['source'])) {
            $where2[] = ['source', '=', $data['source']];
        }

        $subQuery1 = Db::table('o_learning_user')
            ->field('COUNT(learning_id) as learning_total, userid')
            ->where($where1)
            ->group('userid')
            ->buildSql();



        $subQuery3 = Db::table('o_learning_log')
            ->field('SUM(learning_time) as duration, userid')
            ->where($where2)
            ->group('userid')
            ->buildSql();

        $rows = Db::table('o_learning_user')
            ->alias('a')
            ->join($subQuery1.'b','a.userid=b.userid','left')
            ->join($subQuery3.'d','a.userid=d.userid','left')
            ->join('o_members e','a.userid=e.userid','left')
            ->group('a.userid')
            ->where($where)
            ->page($data['page'], 10)
            ->order('d.duration', 'desc')
            ->field('e.name, e.userid, e.department_name, e.division, b.learning_total, d.duration')
            ->select()
            ->toArray();

        if ($rows) {
            foreach ($rows as &$v) {
                if (empty($v['learning_total'])) {
                    $v['learning_total'] = 0;
                }

                if (empty($v['duration'])) {
                    $v['duration'] = 0;
                }

                $learning_id = Db::name('learning_user')
                    ->where('userid', '=', $v['userid'])
                    ->column('learning_id');

                foreach ($learning_id as $key => $val) {

                    $resource = Db::name('learning_step_resource')
                        ->where('learning_id', '=', $val)
                        ->where('status', '=', 1)
                        ->count();

                    $log = Db::name('learning_log')
                        ->where('learning_id', '=', $val)
                        ->where('is_finish', '=', 1)
                        ->where('userid', '=', $v['userid'])
                        ->where($where1)
                        ->group('resource_id')
                        ->count();

                    if ($resource != $log) {
                        unset($learning_id[$key]);
                    }
                }

                $finished_total = count($learning_id);

                $count = mb_strlen($v['userid']);
                if ($count == 6) {
                    if (is_numeric($v['userid'])) {
                        $userid = "'00".$v['userid'];
                    } else {
                        $userid = $v['userid'];
                    }
                } else {
                    $userid = $v['userid'];
                }

                $arr = [
                    $userid,
                    $v['name'],
                    $v['division'],
                    $v['department_name'],
                    $v['learning_total'],
                    $finished_total,
                    $v['duration'],
                ];
                fputcsv($fp, $arr);
            }

            return ['code' => 0, 'ts' => $data['ts'], 'download_id' => $data['download_id'], 'page' => ($data['page'] + 1), 'start' => $data['start'], 'end' => $data['end'], 'key' => $data['key'], 'department' => $data['department']];
        } else {

            return ['code' => 1];
        }
    }


    public function task2(Job $job, array $data)
    {

        $isJobDone = $this->doRecordJobTask2($data);

        if ($isJobDone['code'] == 0) {

            $job->delete();

            // 1.当前任务由哪个类来负责处理
            // 当轮到该任务时，系统将生成该类的实例，并调用其fire方法
            $jobHandlerClassName = 'app\job\JobLearning@task2';

            // 2.当任务归属的队列名称，如果为新队列，会自动创建
            $jobQueueName = "LearningTotalJobQueue";


            // 3.当前任务所需业务数据，不能为resource类型，其他类型最终将转化为json形式的字符串
            $jobData = ['ts' => $isJobDone['ts'], 'download_id' => $isJobDone['download_id'], 'page' => $isJobDone['page'], 'keys' => $isJobDone['keys'], 'close' => $isJobDone['close']];

            // 4.将该任务推送到消息列表，等待对应的消费者去执行
            // 入队列，later延迟执行，单位秒，push立即执行
            Queue::push($jobHandlerClassName, $jobData, $jobQueueName);

        } else if($isJobDone['code'] == 1) {
            $job->delete();
            Db::name('document')->where('id', '=', $data['download_id'])->update(['url' => '/csv/learning/LearningTotalList-'.date('YmdHis', $data['ts']).'.csv', 'complete_time'=>time()]);
        } else {
            if ($job->attempts() > 3) {
                $job->delete();
            }

        }

    }


    /**
     * 根据消息中的数据进行实际的业务处理...
     * @param array $data
     * @return bool
     */
    protected function doRecordJobTask2(array $data)
    {
        $date = date('YmdHis', $data['ts']);
        $file_path = root_path() . "/public/csv/learning/LearningTotalList-".$date.".csv";


        if (!file_exists($file_path)) {
            $fp = fopen($file_path,'a');

            //添加BOM头，以UTF8编码导出CSV文件，如果文件头未添加BOM头，打开会出现乱码。
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));

            //添加导出标题
            fputcsv($fp, ['课程名称','员工工号','员工姓名', 'Division', '部门','注册方式','学习时长(S)','学习时长(H)','开始学习日期','开始学习时间']);
        } else {
            $fp = fopen($file_path,'a');

            //添加BOM头，以UTF8编码导出CSV文件，如果文件头未添加BOM头，打开会出现乱码。
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
        }
        $where = [];

        if (!empty($data['keys'])) {
            $where[] = ['title', 'like', '%'.$data['keys'].'%'];
        }

        if (!empty($data['close'])) {
            $where[] = ['close', '=', $data['close']];
        }

        $where[] = ['status', 'in','1,2'];

        $ids = Db::name('learning')
            ->where($where)
            ->column('id');

        $subQuery1 = Db::table('o_learning_log')
            ->field('SUM(learning_time) as time, userid')
            ->group('userid')
            ->buildSql();

        $rows = Db::name('learning_user')
            ->alias('a')
            ->join('o_members b', 'b.userid=a.userid', 'left')
            ->join('o_learning d', 'd.id=a.learning_id', 'left')
            ->join($subQuery1.'e','e.userid=a.userid','left')
            ->whereIn('a.learning_id', $ids)
            ->where('b.status', '=', 1)
            ->field('a.userid, a.learning_id, a.mode, b.name, b.division, b.department_name, d.title, e.time')
            ->page($data['page'], 10)
            ->select()
            ->toArray();

        if ($rows) {
            foreach($rows as &$value) {

                $count = mb_strlen($value['userid']);
                if ($count == 6) {
                    if (is_numeric($value['userid'])) {
                        $carolid = "'00".$value['userid'];
                    } else {
                        $carolid = $value['userid'];
                    }
                } else {
                    $carolid = $value['userid'];
                }

                $learning_log = Db::name('learning_log')
                    ->where('userid', '=', $value['userid'])
                    ->where('learning_id', '=', $value['learning_id'])
                    ->order('add_time', 'asc')
                    ->find();

                $mode = '';
                if ($value['mode'] == 1) {
                    $mode = '后台导入';
                } elseif ($value['mode'] == 2) {
                    $mode = '小程序注册';
                } elseif ($value['mode'] == 3) {
                    $mode = 'PC端注册';
                }

                $arr = [
                    $value['title'],
                    $carolid,
                    $value['name'],
                    $value['division'],
                    $value['department_name'],
                    $mode,
                    $value['time'],
                    number_format($value['time']/3600, 2),
                    isset($learning_log) ? date('Y-m-d', $learning_log['add_time']) : '----',
                    isset($learning_log) ? date('H:i:s', $learning_log['add_time']) : '----',
                ];
                fputcsv($fp, $arr);
            }
            return ['code' => 0, 'ts' => $data['ts'], 'download_id' => $data['download_id'], 'page' => ($data['page'] + 1), 'keys' => $data['keys'], 'close' => $data['close']];

        } else {

            return ['code' => 1];
        }
    }
}